package analyser.dispatcher;

import analyser.node.AbstractNodeAnalyser;
import analyser.node.INodeAnalyser;
import model.MibModule;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public abstract class NodeAnalyseDispatcher implements INodeAnalyseDispatcher {
    protected Map<String, Class<? extends AbstractNodeAnalyser>> typeAnalyserMap = new HashMap<>();
    protected NodeAnalyseDispatcher next;
    protected List<String> txtList;

    public NodeAnalyseDispatcher(NodeAnalyseDispatcher next) {
        this(next == null ? null : next.txtList, next);
    }

    public NodeAnalyseDispatcher(List<String> txtList) {
        this(txtList, null);
    }

    public NodeAnalyseDispatcher(List<String> txtList, NodeAnalyseDispatcher next) {
        this.next = next;
        this.txtList = txtList;
    }

    @Override
    public INodeAnalyser assign(String type) {
        if (type == null)
            throw new IllegalArgumentException();
        if (typeAnalyserMap.containsKey(type)){
            try {
                return typeAnalyserMap.get(type)
                        .getConstructor(List.class)
                        .newInstance(txtList);
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            }
        }
        return next == null ? null : next.assign(type);
    }

    @Override
    public void init(MibModule module) {
        if (module != null && module.importsModuleNodesMap != null)
            dispatch(module.importsModuleNodesMap);
        if (null != this.next)
            next.init(module);
    }

    protected void dispatch(Map<String, List<String>> importsMap){}

}
